home *** CD-ROM | disk | FTP | other *** search
- ; LEDSHOW.ASM
- ;
- ; This short TSR creates a light show on the keyboard's LEDs. For space
- ; reasons, this code does not implement a multiplex handler nor can you
- ; remove this TSR once installed. See the chapter on resident programs
- ; for details on how to do this.
- ;
- ; cseg and EndResident must occur before the standard library segments!
-
- cseg segment para public 'code'
- cseg ends
-
- ; Marker segment, to find the end of the resident section.
-
- EndResident segment para public 'Resident'
- EndResident ends
-
- .xlist
- include stdlib.a
- includelib stdlib.lib
- .list
-
-
- byp equ <byte ptr>
-
- cseg segment para public 'code'
- assume cs:cseg, ds:cseg
-
-
-
-
-
-
- ; SetCmd- Sends the command byte in the AL register to the 8042
- ; keyboard microcontroller chip (command register at
- ; port 64h).
-
- SetCmd proc near
- push cx
- push ax ;Save command value.
- cli ;Critical region, no ints now.
-
- ; Wait until the 8042 is done processing the current command.
-
- xor cx, cx ;Allow 65,536 times thru loop.
- Wait4Empty: in al, 64h ;Read keyboard status register.
- test al, 10b ;Input buffer full?
- loopnz Wait4Empty ;If so, wait until empty.
-
- ; Okay, send the command to the 8042:
-
- pop ax ;Retrieve command.
- out 64h, al
- sti ;Okay, ints can happen again.
- pop cx
- ret
- SetCmd endp
-
-
-
-
- ; SendCmd- The following routine sends a command or data byte to the
- ; keyboard data port (port 60h).
-
- SendCmd proc near
- push ds
- push bx
- push cx
- mov cx, 40h
- mov ds, cx
- mov bx, ax ;Save data byte
-
- mov al, 0ADh ;Disable kbd for now.
- call SetCmd
-
- cli ;Disable ints while accessing HW.
-
- ; Wait until the 8042 is done processing the current command.
-
- xor cx, cx ;Allow 65,536 times thru loop.
- Wait4Empty: in al, 64h ;Read keyboard status register.
- test al, 10b ;Input buffer full?
- loopnz Wait4Empty ;If so, wait until empty.
-
- ; Okay, send the data to port 60h
-
- mov al, bl
- out 60h, al
-
- mov al, 0AEh ;Reenable keyboard.
- call SetCmd
- sti ;Allow interrupts now.
-
- pop cx
- pop bx
- pop ds
- ret
- SendCmd endp
-
-
- ; SetLEDs- Writes the value in AL to the LEDs on the keyboard.
- ; Bits 0..2 correspond to scroll, num, and caps lock,
- ; respectively.
-
- SetLEDs proc near
- push ax
- push cx
-
- mov ah, al ;Save LED bits.
-
- mov al, 0EDh ;8042 set LEDs cmd.
- call SendCmd ;Send the command to 8042.
- mov al, ah ;Get parameter byte
- call SendCmd ;Send parameter to the 8042.
-
- pop cx
- pop ax
- ret
- SetLEDs endp
-
-
-
- ; MyInt1C- Every 1/4 seconds (every 4th call) this routine
- ; rotates the LEDs to produce an interesting light show.
-
- CallsPerIter equ 4
- CallCnt byte CallsPerIter
- LEDIndex word LEDTable
- LEDTable byte 111b, 110b, 101b, 011b,111b, 110b, 101b, 011b
- byte 111b, 110b, 101b, 011b,111b, 110b, 101b, 011b
- byte 111b, 110b, 101b, 011b,111b, 110b, 101b, 011b
- byte 111b, 110b, 101b, 011b,111b, 110b, 101b, 011b
-
- byte 000b, 100b, 010b, 001b, 000b, 100b, 010b, 001b
- byte 000b, 100b, 010b, 001b, 000b, 100b, 010b, 001b
- byte 000b, 100b, 010b, 001b, 000b, 100b, 010b, 001b
- byte 000b, 100b, 010b, 001b, 000b, 100b, 010b, 001b
-
- byte 000b, 001b, 010b, 100b, 000b, 001b, 010b, 100b
- byte 000b, 001b, 010b, 100b, 000b, 001b, 010b, 100b
- byte 000b, 001b, 010b, 100b, 000b, 001b, 010b, 100b
- byte 000b, 001b, 010b, 100b, 000b, 001b, 010b, 100b
-
- byte 010b, 001b, 010b, 100b, 010b, 001b, 010b, 100b
- byte 010b, 001b, 010b, 100b, 010b, 001b, 010b, 100b
- byte 010b, 001b, 010b, 100b, 010b, 001b, 010b, 100b
- byte 010b, 001b, 010b, 100b, 010b, 001b, 010b, 100b
-
- byte 000b, 111b, 000b, 111b, 000b, 111b, 000b, 111b
- byte 000b, 111b, 000b, 111b, 000b, 111b, 000b, 111b
- byte 000b, 111b, 000b, 111b, 000b, 111b, 000b, 111b
- byte 000b, 111b, 000b, 111b, 000b, 111b, 000b, 111b
- TableEnd equ this byte
-
- OldInt1C dword ?
-
- MyInt1C proc far
- assume ds:cseg
-
- push ds
- push ax
- push bx
-
- mov ax, cs
- mov ds, ax
-
- dec CallCnt
- jne NotYet
- mov CallCnt, CallsPerIter ;Reset call count.
- mov bx, LEDIndex
- mov al, [bx]
- call SetLEDs
- inc bx
- cmp bx, offset TableEnd
- jne SetTbl
- lea bx, LEDTable
- SetTbl: mov LEDIndex, bx
- NotYet: pop bx
- pop ax
- pop ds
- jmp cs:OldInt1C
- MyInt1C endp
-
-
- Main proc
-
- mov ax, cseg
- mov ds, ax
-
- print
- byte "LED Light Show",cr,lf
- byte "Installing....",cr,lf,0
-
- ; Patch into the INT 9 and INT 16 interrupt vectors. Note that the
- ; statements above have made cseg the current data segment,
- ; so we can store the old INT 9 and INT 16 values directly into
- ; the OldInt9 and OldInt16 variables.
-
- cli ;Turn off interrupts!
- mov ax, 0
- mov es, ax
- mov ax, es:[1Ch*4]
- mov word ptr OldInt1C, ax
- mov ax, es:[1Ch*4 + 2]
- mov word ptr OldInt1C+2, ax
- mov es:[1Ch*4], offset MyInt1C
- mov es:[1Ch*4+2], cs
- sti ;Okay, ints back on.
-
-
- ; We're hooked up, the only thing that remains is to terminate and
- ; stay resident.
-
- print
- byte "Installed.",cr,lf,0
-
- mov ah, 62h ;Get this program's PSP
- int 21h ; value.
-
- mov dx, EndResident ;Compute size of program.
- sub dx, bx
- mov ax, 3100h ;DOS TSR command.
- int 21h
- Main endp
- cseg ends
-
- sseg segment para stack 'stack'
- stk db 1024 dup ("stack ")
- sseg ends
-
- zzzzzzseg segment para public 'zzzzzz'
- LastBytes db 16 dup (?)
- zzzzzzseg ends
- end Main
-